package com.example.game2048.view;

import static com.example.game2048.annotation.GridType.GRID_SCALE;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;

import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;

import com.example.game2048.MainActivity;
import com.example.game2048.R;
import com.example.game2048.Grid;
import com.example.game2048.bean.Pile;
import com.example.game2048.bean.Position;

/**
 * GridView 是视图类，主要进行UI操作
 */
public class GridView extends View {
    private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);

    private float lastX,lastY,X,Y;
    private int minDim;
    private int pileSize;

    private Grid grid;

    private TextView scoreText;
    private MainActivity activity;

    public GridView(Context context) {
        super(context);
        initView();
    }

    public GridView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    public GridView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
    }

    private void initView(){
        paint.setTextSize(100f);
        grid = new Grid();
    }
    public void setActivity(MainActivity activity){
        this.activity = activity;
    }
    public void setScoreText(TextView textView){scoreText = textView;}
    @Override
    protected void onDraw(Canvas canvas){
        super.onDraw(canvas);

        if(grid.getPileList().isEmpty()){
            int width = canvas.getWidth();
            int height = canvas.getHeight();

            minDim = Math.min(width,height);
            pileSize = minDim / GRID_SCALE;
            //pileSize必须能整除4才能移动到正确位置
            if(pileSize% GRID_SCALE != 0)
                pileSize -= pileSize % GRID_SCALE;
            grid.initGrid(GRID_SCALE,pileSize);
        }

        paint.setColor(ContextCompat.getColor(getContext(),R.color.grey));
        canvas.drawRect(0,0,minDim,minDim,paint);

        drawTitles(canvas);

        canvas.save();
    }


    private void drawTitles(Canvas canvas){
        grid.getPileList().forEach(pile -> {
            String colorName = "color"+pile.getValue();
            paint.setColor(ContextCompat.getColor(getContext(),
                    getResources().getIdentifier(colorName,"color",getContext().getPackageName())));

            canvas.drawRect(
                    pile.getActualX(),
                    pile.getActualY(),
                    pile.getActualX() + pileSize,
                    pile.getActualY() + pileSize,
                    paint
            );
            paint.setColor(ContextCompat.getColor(getContext(),R.color.black));
            canvas.drawText(String.valueOf(pile.getValue()),
                    (float) (pile.getActualX() + 0.4 * pileSize),
                    (float) (pile.getActualY() + 0.6 * pileSize),
                    paint);

        });
        scoreText.setText(String.valueOf(grid.getScore()));
    }

    private void graduallyMovePile(Pile pile, Position position){
        new Thread(()->{
            int dimX = 0,dimY = 0;
            try {
                if(pile.getActualY() != position.getY()){
                    dimY = (position.getY() - pile.getActualY())/10;
                }
                if(pile.getActualX() != position.getX()){
                    dimX = (position.getX() - pile.getActualX())/10;
                }
                if(dimX==0&&dimY==0)
                    return;
                for(int i=0;i<10;i++){
                    Thread.sleep(10);
                    pile.setActualX(pile.getActualX()+dimX);
                    pile.setActualY(pile.getActualY()+dimY);
                    if(i==9){
                        pile.setActualX(position.getX());
                        pile.setActualY(position.getY());
                    }
                    invalidate();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();

    }



    @Override
    public boolean onTouchEvent(MotionEvent event){
        switch (event.getActionMasked()){
            case MotionEvent.ACTION_DOWN:
                lastX=event.getX();
                lastY=event.getY();
                return true;
            case MotionEvent.ACTION_UP:
                X=event.getX();
                Y=event.getY();
                if(Math.abs(X-lastX)>Math.abs(Y-lastY)){
                    //右
                    if(X-lastX>0){
                        grid.rightMotion();

                    } else{//左
                        grid.leftMotion();
                    }
                    //下
                }else{
                    if(Y-lastY>0){
                        grid.downMotion();
                    } else{//上
                        grid.upMotion();
                    }
                }
                grid.getUnEmptyPositionList().forEach(position -> graduallyMovePile(position.getPile(),position));
                if(anyPileIsMoved()){
                    if(!grid.insertNewPile()){
                        //game over
                    }
                }


                return true;
        }
        return false;
    }

    private boolean anyPileIsMoved(){
        for (Pile pile : grid.getPileList()) {
            if(pile.isMove())
                return true;
        }
        return false;
    }

    public void restart(){
        initView();
        invalidate();
    }
}
